package com.wlyuan.open.scanner.repository.impl;

import com.wlyuan.open.scanner.assembler.ScannerCombineAssembler;
import com.wlyuan.open.scanner.constant.Constants;
import com.wlyuan.open.scanner.dao.entity.OrderIndexDO;
import com.wlyuan.open.scanner.dao.mapper.OrderIndexMapper;
import com.wlyuan.open.scanner.domain.combine.Combine;
import com.wlyuan.open.scanner.domain.combine.CombineConvert;
import com.wlyuan.open.scanner.repository.CustomerRepository;
import com.wlyuan.open.scanner.repository.OrderCombineRepository;
import com.wlyuan.open.scanner.repository.OrderContainRepository;
import com.wlyuan.open.scanner.utils.enums.YesOrNoEnum;
import com.wlyuan.open.scanner.utils.enums.transport.combine.CombineStatusEnum;
import com.wlyuan.open.utils.LongUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * @author lijing
 * @description
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderCombineRepositoryImpl implements OrderCombineRepository {
    private final OrderIndexMapper orderIndexMapper;
    private final BaseOrderRepository baseOrderRepository;
    private final OrderContainRepository orderContainRepository;
    private final BaseCostRepository baseCostRepository;
    private final CustomerRepository customerRepository;

    @Override
    public void sync() {
        logger.info("Index_SrcClass = 3 and Index_Status <> 0 and Index_Status <> -1");
        var count = orderIndexMapper.combineCount();
        logger.info("拼车单老数据数据量，size：{}", count);
        var pages = (int) Math.ceil(count * 1.0 / Constants.PAGE_SIZE);
        for (int i = 1; i <= pages; i++) {
            logger.info("开始同步拼车单：第{}页，共{}页", i, pages);
            var list = orderIndexMapper.combineIds(i, Constants.PAGE_SIZE);
            list.forEach(id -> {
                try {
                    var data = orderIndexMapper.getById(id);
                    if (baseOrderRepository.checkTenant(data.getIndexCreatorcompanyid())) {
                        logger.error("合单id：{},租户id:{}", id, data.getIndexCreatorcompanyid());
                        baseOrderRepository.syncRef(null);
                    } else {
                        Optional.ofNullable(data).ifPresent(order -> {
                            process(order);
                            baseOrderRepository.syncRef(ScannerCombineAssembler.assemble(CombineConvert.convert(order)));
                        });
                    }

                } catch (Exception e) {
                    logger.error("拼车单同步异常：{}，{}", id, e);
                }
            });
        }
        logger.info("拼车单同步完成......");
    }

    @Override
    public List<Combine> combineList() {
        return Collections.emptyList();
    }

    @Override
    public Combine getById(Long combineId) {
        return Optional.ofNullable(combineId).map(id -> {
            var data = orderIndexMapper.getById(id);
            return Optional.ofNullable(data).map(transport -> {
                process(transport);
                return CombineConvert.convert(transport);
            }).orElse(null);
        }).orElse(null);
    }

    @Override
    public List<Long> getByTime(String startTime, String endTime) {
        return orderIndexMapper.getCombineIdByTime(startTime, endTime);
    }

    @Override
    public List<Long> getByTenantIdTime(Long tenantId, String startTime, String endTime) {
        return orderIndexMapper.getCombineIdByTenantIdTime(tenantId, startTime, endTime);
    }

    @Override
    public void getByTenantId(Long tenantId) {
        logger.info("Index_SrcClass = 3 and Index_Status <> 0 and Index_Status <> -1");
        var count = orderIndexMapper.combineCountByTenantId(tenantId);
        logger.info("租户{}拼车单老数据数据量，size：{}", tenantId, count);
        var pages = (int) Math.ceil(count * 1.0 / Constants.PAGE_SIZE);
        for (int i = 1; i <= pages; i++) {
            logger.info("开始同步租户{}拼车单：第{}页，共{}页", tenantId, i, pages);
            var list = orderIndexMapper.combineByTenantId(i, Constants.PAGE_SIZE, tenantId);
            list.forEach(id -> {
                try {
                    var data = orderIndexMapper.getById(id);
                    Optional.ofNullable(data).ifPresent(order -> {
                        process(order);
                        baseOrderRepository.syncRef(ScannerCombineAssembler.assemble(CombineConvert.convert(order)));
                    });
                } catch (Exception e) {
                    logger.error("拼车单同步异常：{}，{}", id, e);
                }
            });
        }
        logger.info("租户{}拼车单同步完成......", tenantId);
    }

    @Override
    public void process(OrderIndexDO data) {
        var orderId = data.getIndexId();
        //子单集合
        data.setChildrenTransportIds(orderContainRepository.getOrderContainByOrderId(orderId));
        //承运商
        baseOrderRepository.processCarrier(data);
        //调度
        baseOrderRepository.dispatch(data);
        //关单
        baseOrderRepository.close(data);
        //费用信息
        baseCostRepository.cost(data, null, true);
        //多段轨迹
        data.setTransports(baseOrderRepository.getOrderAdditionTransport(orderId, data.isAdditionTransportType()));
        //合单类型
        data.setTransportType(combineType(data.getChildrenTransportIds(), data.getIndexCreatorcompanyid()));
        //客户信息，根据租户id去查询
        var ownerCompanyId = LongUtils.notNullLong(data.getIndexSuppliercompanyid()) ? data.getIndexSuppliercompanyid() : data.getIndexCreatorcompanyid();
        Optional.ofNullable(customerRepository.getByCompanyId(ownerCompanyId, data.getIndexCreatorcompanyid())).ifPresent(c -> {
            data.setIndexCustomerid(c.getId());
            data.setCustomerName(c.getName());
            data.setCustomerType(c.getType());
            data.setDownTenantId(c.getTenantId());
        });
        //无效的，状态设置为已关闭
        if (YesOrNoEnum.isNo(data.getIndexInvalid())) {
            data.setIndexStatus(CombineStatusEnum.CLOSED.getValue());
        }
    }

    private Integer combineType(List<Long> children, Long tenantId) {
        if (Constants.TOP_TENANT.equals(tenantId)) {
            return Optional.ofNullable(orderIndexMapper.getFullCombine(children)).map(x -> 2).orElse(1);
        }
        return null;
    }
}
